package com.example.graphmovieapp.controller;

import com.example.graphmovieapp.domain.entity.Person;
import com.example.graphmovieapp.domain.entity.Movie;
import com.example.graphmovieapp.service.PersonService;
import com.example.graphmovieapp.service.MovieService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import jakarta.validation.Valid;

import java.util.List;
import java.util.Optional;

/**
 * PersonController类，提供人物相关的REST API端点
 * 
 * @author GraphMovieApp
 * @version 1.0
 */
@RestController
@RequestMapping("/api/persons")
public class PersonController {

    private final PersonService personService;
    private final MovieService movieService;

    /**
     * 构造函数，注入Service依赖
     *
     * @param personService 人物服务
     * @param movieService 电影服务
     */
    @Autowired
    public PersonController(PersonService personService, MovieService movieService) {
        this.personService = personService;
        this.movieService = movieService;
    }

    /**
     * 创建人物
     * 
     * @param person 要创建的人物
     * @return 创建后的人物
     */
    @PostMapping
    public ResponseEntity<Person> createPerson(@Valid @RequestBody Person person) {
        try {
            Person savedPerson = personService.savePerson(person);
            return new ResponseEntity<>(savedPerson, HttpStatus.CREATED);
        } catch (IllegalArgumentException e) {
            return new ResponseEntity<>(null, HttpStatus.BAD_REQUEST);
        }
    }

    /**
     * 根据ID获取人物
     * 
     * @param id 人物ID
     * @return 匹配的人物
     */
    @GetMapping("/{id}")
    public ResponseEntity<Person> getPersonById(@PathVariable Long id) {
        try {
            Optional<Person> person = personService.findPersonById(id);
            return person.map(value -> new ResponseEntity<>(value, HttpStatus.OK))
                    .orElseGet(() -> new ResponseEntity<>(HttpStatus.NOT_FOUND));
        } catch (IllegalArgumentException e) {
            return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
        }
    }

    /**
     * 获取所有人物
     * 
     * @return 所有人物列表
     */
    @GetMapping
    public ResponseEntity<List<Person>> getAllPersons() {
        List<Person> persons = personService.findAllPersons();
        return new ResponseEntity<>(persons, HttpStatus.OK);
    }

    /**
     * 删除人物
     * 
     * @param id 人物ID
     * @return 操作结果
     */
    @DeleteMapping("/{id}")
    public ResponseEntity<Void> deletePerson(@PathVariable Long id) {
        try {
            personService.deletePerson(id);
            return new ResponseEntity<>(HttpStatus.NO_CONTENT);
        } catch (IllegalArgumentException e) {
            return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
        }
    }

    /**
     * 根据姓名获取人物
     * 
     * @param name 人物姓名
     * @return 匹配的人物
     */
    @GetMapping("/by-name")
    public ResponseEntity<Person> getPersonByName(@RequestParam String name) {
        try {
            Optional<Person> person = personService.findPersonByName(name);
            return person.map(value -> new ResponseEntity<>(value, HttpStatus.OK))
                    .orElseGet(() -> new ResponseEntity<>(HttpStatus.NOT_FOUND));
        } catch (IllegalArgumentException e) {
            return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
        }
    }

    /**
     * 根据出生年份获取人物
     * 
     * @param born 出生年份
     * @return 匹配的人物列表
     */
    @GetMapping("/by-born")
    public ResponseEntity<List<Person>> getPersonsByBorn(@RequestParam Integer born) {
        try {
            List<Person> persons = personService.findPersonsByBorn(born);
            return new ResponseEntity<>(persons, HttpStatus.OK);
        } catch (IllegalArgumentException e) {
            return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
        }
    }

    /**
     * 姓名模糊查询（分页）
     * 
     * @param name 姓名关键字
     * @param page 页码（从0开始）
     * @param size 每页大小
     * @return 分页的人物列表
     */
    @GetMapping("/search")
    public ResponseEntity<Page<Person>> searchPersonsByName(
            @RequestParam String name,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size) {
        try {
            Pageable pageable = PageRequest.of(page, size);
            Page<Person> persons = personService.findPersonsByNameContaining(name, pageable);
            return new ResponseEntity<>(persons, HttpStatus.OK);
        } catch (IllegalArgumentException e) {
            return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
        }
    }

    /**
     * 获取人物参演的电影
     * 
     * @param id 人物ID
     * @return 该人物参演的电影列表
     */
    @GetMapping("/{id}/movies-acted")
    public ResponseEntity<List<Movie>> getMoviesActedByPerson(@PathVariable Long id) {
        try {
            Optional<Person> personOpt = personService.findPersonById(id);
            if (!personOpt.isPresent()) {
                return new ResponseEntity<>(HttpStatus.NOT_FOUND);
            }
            
            List<Movie> movies = personService.findMoviesActedByPerson(personOpt.get().getName());
            return new ResponseEntity<>(movies, HttpStatus.OK);
        } catch (IllegalArgumentException e) {
            return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
        }
    }

    /**
     * 获取人物执导的电影
     * 
     * @param id 人物ID
     * @return 该人物执导的电影列表
     */
    @GetMapping("/{id}/movies-directed")
    public ResponseEntity<List<Movie>> getMoviesDirectedByPerson(@PathVariable Long id) {
        try {
            Optional<Person> personOpt = personService.findPersonById(id);
            if (!personOpt.isPresent()) {
                return new ResponseEntity<>(HttpStatus.NOT_FOUND);
            }
            
            List<Movie> movies = personService.findMoviesDirectedByPerson(personOpt.get().getName());
            return new ResponseEntity<>(movies, HttpStatus.OK);
        } catch (IllegalArgumentException e) {
            return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
        }
    }

    /**
     * 添加演员到电影
     *
     * @param personId 人物ID
     * @param movieId 电影ID
     * @return 操作结果
     */
    @PostMapping("/{personId}/act-in/{movieId}")
    public ResponseEntity<Void> addActorToMovie(
            @PathVariable Long personId,
            @PathVariable Long movieId) {
        try {
            // 通过ID查找人物
            Optional<Person> personOpt = personService.findPersonById(personId);
            if (!personOpt.isPresent()) {
                return new ResponseEntity<>(HttpStatus.NOT_FOUND);
            }
            
            // 通过ID查找电影
            Optional<Movie> movieOpt = movieService.findMovieById(movieId);
            if (!movieOpt.isPresent()) {
                return new ResponseEntity<>(HttpStatus.NOT_FOUND);
            }
            
            // 使用姓名建立关系
            Person person = personOpt.get();
            Movie movie = movieOpt.get();
            personService.addActorToMovie(person.getName(), movie.getTitle());
            
            return new ResponseEntity<>(HttpStatus.OK);
        } catch (IllegalArgumentException e) {
            return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
        }
    }

    /**
     * 添加导演到电影
     *
     * @param personId 人物ID
     * @param movieId 电影ID
     * @return 操作结果
     */
    @PostMapping("/{personId}/direct/{movieId}")
    public ResponseEntity<Void> addDirectorToMovie(
            @PathVariable Long personId,
            @PathVariable Long movieId) {
        try {
            // 通过ID查找人物
            Optional<Person> personOpt = personService.findPersonById(personId);
            if (!personOpt.isPresent()) {
                return new ResponseEntity<>(HttpStatus.NOT_FOUND);
            }
            
            // 通过ID查找电影
            Optional<Movie> movieOpt = movieService.findMovieById(movieId);
            if (!movieOpt.isPresent()) {
                return new ResponseEntity<>(HttpStatus.NOT_FOUND);
            }
            
            // 使用姓名建立关系
            Person person = personOpt.get();
            Movie movie = movieOpt.get();
            personService.addDirectorToMovie(person.getName(), movie.getTitle());
            
            return new ResponseEntity<>(HttpStatus.OK);
        } catch (IllegalArgumentException e) {
            return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
        }
    }
}